﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using GrupyzServices.BdAccess;
using PreBuildGrupyz.Models;
using AutoMapper;


namespace PreBuildGrupyz.Controllers
{
    public class CheckoutController : Controller
    {
        IOrderRepository _repository;

        public CheckoutController()
            : this(new OrderRepository())
        { }

        public CheckoutController(OrderRepository repository)
        {
            _repository = repository;
        }


        //
        // GET: /Checkout/
        [Authorize]
        public ActionResult Checkout()
        {
            if (User.Identity.IsAuthenticated)
                return View(_repository.FillOrderCliente(int.Parse(User.Identity.Name)));
            else
                return View(new Order.OrderViewModel());
        }

        [Authorize]
        [HttpPost]
        public ActionResult Checkout(DAL.Order order)
        {
            if (ModelState.IsValid)
            {
                var cart = ShoppingCart.GetCart(this.HttpContext);
                
                _repository.CreateOrder(ref order, int.Parse(User.Identity.Name), cart.GetTotalPontos(),cart.GetValorDesconto());
                cart.CreateOrder(order);

                //Se o valor for 0 não entrar no paypal, finalizar a compra
                if (order != null)
                {
                    if (order.Total == 0)
                    {
                        FinalOrderViewModel f = FinalizaCompra(order);
                        if (f != null)
                        {
                            return View("CheckoutOK", f);
                        }
                        else
                        {
                            ViewData["ErrorMSG"] = "Erro ao concluir o pagamento.";
                            _repository.DeleteOrder(order.Id);
                            return View("CheckoutError");
                        }
                    }

                    Session["orderId"] = order.Id;
                    NVPAPICaller test = new NVPAPICaller();
                    string retMsg = "";
                    string token = "";
                    string amt = string.Format("{0:#.##}", order.Total).Replace(',', '.');

                    if (amt != null)
                    {
                        bool ret = test.ShortcutExpressCheckout(amt, ref token, ref retMsg, _repository.GetFinalOrderDetail(order.Id));
                        if (ret)
                        {
                            //Session["token"] = token;
                            Response.Cookies.Add(new HttpCookie(token, amt));
                            Response.Cookies.Add(new HttpCookie(token + "-order", order.Id.ToString()));
                            Response.Redirect(retMsg);
                        }
                        else
                        {
                            ViewData["ErrorMSG"] = retMsg;
                            _repository.DeleteOrder(order.Id);
                            return View("CheckoutError");
                        }
                    }
                    else
                    {
                        ViewData["ErrorMSG"] = "Ocorreu um erro ao processar o seu pedido. <b />Caso o problema persista entre em contacto com o administrador.";
                        _repository.DeleteOrder(order.Id);
                        return View("CheckoutError");
                    }
                    return View("CheckoutOK", new FinalOrderViewModel());
                }
            }
            ViewData["ErrorMSG"] = "Ocorreu um erro ao processar o seu pedido. <b />Caso o problema persista entre em contacto com o administrador.";
            _repository.DeleteOrder(order.Id);
            return View("CheckoutError");
        }


        public ActionResult CheckoutOK()
        {
            //if (PaymentOption == "PayPal")
            //{
            NVPAPICaller test = new NVPAPICaller();

            string retMsg = "";
            string token = Request.QueryString["token"];
            string payerId = Request.QueryString["payerId"];

            int orderId = int.Parse(Request.Cookies[token + "-order"].Value);

            DAL.Order order = _repository.GetOrderById(orderId);

            bool ret = test.GetShippingDetails(token, ref payerId, ref order, ref retMsg);
            if (ret)
            {
                Session["payerId"] = payerId;
                //Response.Write(shippingAddress);
            }
            else
            {
                ViewData["ErrorMSG"] = retMsg;
                _repository.DeleteOrder(order.Id);
                return View("CheckoutError");
            }

            string finalPaymentAmount = Request.Cookies[token].Value;

            NVPCodec decoder = new NVPCodec();
            //Session["payment_amt"] = "10.00";

            //finalPaymentAmount = Session["payment_amt"].ToString();

            ret = test.ConfirmPayment(finalPaymentAmount, token, payerId, ref decoder, ref retMsg);
            if (ret)
            {
                // Unique transaction ID of the payment. Note:  If the PaymentAction of the request was Authorization or Order, this value is your AuthorizationID for use with the Authorization & Capture APIs. 
                string transactionId = decoder["TRANSACTIONID"];
                order.IdPaypal = transactionId;

                // The type of transaction Possible values: l  cart l  express-checkout 
                string transactionType = decoder["TRANSACTIONTYPE"];

                // Indicates whether the payment is instant or delayed. Possible values: l  none l  echeck l  instant 
                string paymentType = decoder["PAYMENTTYPE"];

                // Time/date stamp of payment
                string orderTime = decoder["ORDERTIME"];

                // The final amount charged, including any shipping and taxes from your Merchant Profile.
                string amt = decoder["AMT"];

                // A three-character currency code for one of the currencies listed in PayPay-Supported Transactional Currencies. Default: USD.    
                string currencyCode = decoder["CURRENCYCODE"];

                // PayPal fee amount charged for the transaction    
                string feeAmt = decoder["FEEAMT"];

                // Amount deposited in your PayPal account after a currency conversion.    
                string settleAmt = decoder["SETTLEAMT"];

                // Tax charged on the transaction.    
                string taxAmt = decoder["TAXAMT"];

                //' Exchange rate if a currency conversion occurred. Relevant only if your are billing in their non-primary currency. If 
                string exchangeRate = decoder["EXCHANGERATE"];
            }
            else
            {
                ViewData["ErrorMSG"] = retMsg;
                _repository.DeleteOrder(order.Id);
                return View("CheckoutError");
            }

            return View(FinalizaCompra(order));
        }

        public ActionResult CheckoutError()
        {
            //limpar esta order
            _repository.DeleteOrder(int.Parse(Session["orderId"].ToString()));
            
            return RedirectToAction("Index","Home");
        }

        private FinalOrderViewModel FinalizaCompra(DAL.Order order)
        {
            try
            {
                FinalOrderViewModel fo = _repository.ActualizaOrder(order);

                //WebService.FinalOrderViewModel forder = new WebService.FinalOrderViewModel();
                //forder.Concluido = fo.Concluido;
                //forder.dealId = fo.dealId;
                //forder.Desconto = fo.Desconto;
                //forder.Descricao = fo.Descricao;
                //forder.Email = fo.Email;
                //forder.EmailDest = fo.EmailDest;
                //forder.Pontos = fo.Pontos;
                ////forder.IdPaypal =

                //Mapper.CreateMap<FinalOrderViewModel, WebService.FinalOrderViewModel>();
                //Mapper.Map(fo, forder);

                //WebService.Processos proc = new WebService.Processos();

                if (fo.Concluido)
                {
                    _repository.DealConcluido(fo);
                }
                else
                {
                    _repository.DealPorConcluir(fo);
                }

                return fo;
            }
            catch (Exception)
            {
                return null;
            }
        }
    }
}
